#include "MyTcpServer.h"

MyTcpServer::MyTcpServer(QTcpServer *parent)
    : QTcpServer{parent}
    // , var_socket(nullptr)
    // , current_client_info(new ClientInfo)
    , thread_count(0)
{

}

MyTcpServer::MyTcpServer(qintptr socketDescriptor, QTcpServer *parent)
    : QTcpServer{parent}
    // , var_socket(nullptr)
    // , current_client_info(new ClientInfo)
    , my_socketDescriptor(socketDescriptor)
    , thread_count(0)
{
    // qDebug() << thread_count;
}

MyTcpServer::~MyTcpServer()
{
    // client_thread->quit();  // 退出线程
    // client_thread->wait();  // 等待退出
    // delete client_thread;   // 释放资源
    for (QPair<ClientHandle*, QThread*> sub_client: std::as_const(my_client))
    {
        sub_client.first->~ClientHandle();
        delete sub_client.first;
        sub_client.second->quit();  // 退出线程
        sub_client.second->wait();  // 等待退出
        delete sub_client.second;   // 释放资源
    }
    my_client.clear();
}


const QVector<QPair<ClientHandle*, QThread*>> MyTcpServer::get_my_client()
{
    return my_client;
}

const ClientInfo* MyTcpServer::get_current_message()
{
    return current_message;
}

const int MyTcpServer::get_thread_count()
{
    return thread_count;
}


void MyTcpServer::incomingConnection(qintptr socketDescriptor)
{ // 客户端发起连接，自动触发该函数
    my_socketDescriptor = socketDescriptor;

    // 创建并启动线程
    QThread* sub_thread = new QThread;
    ClientHandle* client = new ClientHandle(socketDescriptor);
    QPair<ClientHandle*, QThread*> sub_client(client, sub_thread);
    // connect(sub_thread, &QThread::finished, client, &TestObject::deleteLater);	// 退出后释放TestObject对象资源
    // connect(sub_thread, &QThread::finished, sub_thread, &QThread::deleteLater);	// 退出后释放QThread对象资源

    my_client.push_back(sub_client);     // 客户端、线程元组对象
    client->moveToThread(sub_thread);    // 移动到线程中
    sub_thread->start();    // 在子线程中启动
    QObject::connect(this, &MyTcpServer::signal_to_thread, client, &ClientHandle::working);
    emit signal_to_thread();

    // 连接线程计数增加
    qDebug() << ++thread_count;
    emit send_thread_count_signal();

    // 获取客户端发送的消息
    QObject::connect(client, &ClientHandle::send_message_to_server_signal, this, &MyTcpServer::get_client_message_slot);

    // 断开连接信号连接到对应函数
    QObject::connect(client, &ClientHandle::disconnect_signal, this, &MyTcpServer::thread_disconnect_signal);
}


void MyTcpServer::get_client_message_slot(const ClientInfo* clint_info)
{
    current_message = const_cast<ClientInfo*>(clint_info);

    // 发消息给 Ui
    emit send_message_to_widget_signal();
}


void MyTcpServer::thread_disconnect_signal(ClientHandle* client)
{
    // 连接线程计数减少
    qDebug() << --thread_count;

    // 释放内存
    auto sub_client = my_client.begin();
    // for ( ; sub_client != my_client.end(); ++sub_client)
    //     qDebug() << "换行\n";

    // sub_client = my_client.begin();
    for ( ; sub_client != my_client.end(); )
    {   // begin() 和 end() 返回的其实是 range 迭代器的对应指针
        if (sub_client->first == client)
        {
            delete sub_client->first;
            sub_client->second->quit();  // 退出线程
            sub_client->second->wait();  // 等待退出
            delete sub_client->second;
            sub_client = my_client.erase(sub_client); // 重新定向到当前位置，erase 会将 sub_client 置空指针，并返回其所在位置
            break;  // 一个客户端只会连一个 socket 每个客户端的地址都不同，所以断一次删对应的一个就行
        }
        else
        {
            ++sub_client;   // 删除多个时的正确逻辑
        }
    }

    // sub_client = my_client.begin();
    // for ( ; sub_client != my_client.end(); ++sub_client)
    //     qDebug() << "删除后计数\n";

    // 线程计数减少信号
    emit send_thread_count_signal();
}
